<template>
  <el-form ref="elFormRef" :label-position="labelPosition" :rules="rules" :label-width="labelWidth" :model="formData">
    <el-row v-for="(formItems, index) in formItemss" :key="index" :gutter="gutter">
      <template v-for="it in formItems.item" :key="it.submitTitle">
        <el-col :sm="it.sm" :md="it.md" :lg="it.lg" :xl="it.xl" :offset="it.offset">
          <el-form-item :label="it.label" :prop="it.value">
            <template v-if="it.type == 'input'">
              <el-input
                v-model="formData[it.value]"
                :size="it.size"
                :disabled="it.disable ? true : false"
                style="background-color: transparent"
                :placeholder="it.placeholder"
                :clearable="it.clearn"
                auto-complete="new-password"
              />
            </template>
            <template v-if="it.type == 'inputandtrim'">
              <el-input
                v-model.trim="formData[it.value]"
                :size="it.size"
                :disabled="it.disable ? true : false"
                style="background-color: transparent"
                :placeholder="it.placeholder"
                auto-complete="new-password"
              />
            </template>

            <template v-if="it.type == 'pwd'">
              <el-input
                v-model="formData[it.value]"
                :size="it.size"
                type="password"
                show-password
                :placeholder="it.placeholder"
                auto-complete="new-password"
              />
            </template>

            <template v-if="it.type == 'textarea'">
              <el-input v-model="formData[it.value]" :autosize="{ minRows: 8, maxRows: 8 }" type="textarea" :placeholder="it.placeholder" />
            </template>

            <template v-if="it.type == 'select'">
              <el-select
                v-model="formData[it.value]"
                :size="it.size"
                :clearable="it.clearn"
                :disabled="it.disable ? true : false"
                placeholder="Select"
              >
                <el-option v-for="item in it.options" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </template>

            <template v-if="it.type == 'submit' && submit">
              <el-button :size="it.size" type="primary" @click="submit(formData)">{{ it.submitTitle }}</el-button>
            </template>

            <template v-if="it.type == 'file'">
              <el-upload
                ref="uploadRef"
                style="width: 100%"
                class="upload-demo"
                drag
                :on-change="change"
                :on-remove="remove"
                :file-list="formData.fileList"
                multiple
                :auto-upload="false"
              >
                <el-icon class="el-icon--upload"><upload-filled /></el-icon>
                <div class="el-upload__text">请上传文件</div>
                <template #tip>
                  <div class="el-upload__tip" style="width: 100%">拖动文件到上传狂，可进行文件上传</div>
                </template>
              </el-upload>

              <!-- <el-button class="ml-3" type="success" @click="submitUpload">
                确认上传文件
              </el-button> -->
            </template>

            <template v-if="it.type == 'fileImage'">
              <el-upload
                name="files"
                class="avatar-uploader"
                :action="it.uploadLink"
                :show-file-list="false"
                :on-success="(response: any) => {formData[it.value] = (baseUrl + response.data)}"
                :before-upload="() => {}"
              >
                <img v-if="formData[it.value]" style="width: 175px; height: 175px" :src="formData[it.value]" class="avatar" />
                <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
              </el-upload>
            </template>

            <template v-if="it.type == 'filebtn'">
              <el-upload
                ref="uploadRef"
                class="avatar-uploader"
                style="width: 100%"
                :on-change="change"
                :on-remove="remove"
                :file-list="formData.fileList"
                multiple
                :auto-upload="false"
              >
                <el-button type="primary">上传文件</el-button>
              </el-upload>

              <!-- <el-button class="ml-3" type="success" @click="submitUpload">
                确认上传文件
              </el-button> -->
            </template>

            <template v-if="it.type == 'datePickerRange'">
              <el-date-picker
                v-model="formData[it.value]"
                type="daterange"
                :size="it.size"
                unlink-panels
                range-separator="-"
                start-placeholder="开始"
                end-placeholder="结束"
              />
            </template>

            <template v-if="it.type == 'btn'">
              <el-button :size="it.size" :type="it.btnType" @click=";(it.click as any)(formData)">{{ it.submitTitle }}</el-button>
            </template>

            <template v-if="it.type == 'radio'">
              <el-radio-group v-model="formData[it.value]">
                <template v-for="item in it.options" :key="'radio' + item.value">
                  <el-radio :size="it.size" :label="item.value">{{ item.label }}</el-radio>
                </template>
              </el-radio-group>
            </template>

            <template v-if="it.type == 'rich'">
              <div style="border: 1px solid #ccc; width: 100%">
                <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" mode="default" />
                <Editor
                  v-model="formData[it.value]"
                  style="height: calc(100vh - 525px); overflow-y: hidden"
                  :defaultConfig="editorConfig"
                  mode="default"
                  @onCreated="handleCreated"
                />
              </div>
            </template>
          </el-form-item>
        </el-col>
      </template>
    </el-row>
  </el-form>
</template>

<script setup lang="ts">
import { reactive, watch, ref, shallowRef } from 'vue'
import type { yoform } from '@/types/yoformItem'
import type { UploadInstance } from 'element-plus'

import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()
const baseUrl = ref(import.meta.env.VITE_BASE_URL)
const toolbarConfig = {}
const editorConfig = {
  placeholder: '请输入内容...',
  MENU_CONF: {
    uploadImage: {
      server: import.meta.env.VITE_BASE_URL + '/common/upload',

      maxFileSize: 4 * 1024 * 1024, // 1M
      // 最多可上传几个文件，默认为 100
      maxNumberOfFiles: 10,
      // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
      allowedFileTypes: [],
      // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
      fieldName: 'files',
      meta: {
        //官网中把token放到了这里，但是请求的时候会看不到token
      },
      headers: {
        //所以token放这里
        // token: window.sessionStorage.token
      },
      // 将 meta 拼接到 url 参数中，默认 false
      metaWithUrl: false,
      // 跨域是否传递 cookie ，默认为 false
      withCredentials: false,
      // 超时时间，默认为 10 秒
      timeout: 5 * 1000, // 5 秒
      customInsert(res: any, insertFn: any) {
        // JS 语法
        // res 即服务端的返回结果
        // 从 res 中找到 url alt href ，然后插图图片
        insertFn(baseUrl.value + res.data)
      }
    },
    uploadVideo: {
      server: import.meta.env.VITE_BASE_URL + '/common/upload',
      fieldName: 'files',
      maxFileSize: 500 * 1024 * 1024,
      customInsert(res: any, insertFn: any) {
        // JS 语法
        // res 即服务端的返回结果
        // 从 res 中找到 url alt href ，然后插图图片
        insertFn(baseUrl.value + res.data)
      }
    }
  }
}
const handleCreated = (editor: any) => {
  editorRef.value = editor // 记录 editor 实例，重要！
}

// 传值
const props = withDefaults(
  defineProps<{
    labelPosition: 'left' | 'right' | 'top'
    labelWidth: string
    gutter: number
    // form配置列表
    formItemss: yoform
    obj: any
    edit?: boolean
    submit?: (obj: any) => void
  }>(),
  {
    edit: false,
    submit: () => {
      console.log('未提供提交方法')
    }
  }
)

// const baseUrl = import.meta.env.VITE_BASE_URL

const uploadRef = ref<UploadInstance>()
// const fileList: Ref<any[]> = ref([])

// 获取表单验证
const rules = reactive<any>({})
props.formItemss.forEach(formItems => {
  formItems.item.forEach(it => {
    rules[it.value] = it.rules
  })
})

// 表单对象
let formData: any = reactive({})
let elFormRef = ref()

// 文件列表
let file_list: any[] = []
// 文件改变事件
const change = (file: any) => {
  file_list.push(file.raw)
  formData.file = file_list
}
// 文件移除事件
const remove = (file: any) => {
  file_list = file_list.filter((it: any) => {
    return it.name !== file.name
  })
  formData.file = file_list
}

//子组件校验，传递到父组件
const validateForm = async () => {
  let flag = null
  await elFormRef.value.validate((valid: boolean) => {
    if (valid) {
      flag = true
    } else {
      flag = false
    }
  })
  return flag
}

// 监听数据源的变化,并赋值到表单数据
watch(
  () => props.obj,
  newVal => {
    if (!props.edit) {
      for (let key in newVal) {
        // 相当于复制他的值而不是复制整个对象的地址，做到数据不会相互影响
        formData[key] = newVal[key]
      }
    } else {
      formData = newVal
    }
  },
  { immediate: true }
)

// 向父组件暴露出formData对象
defineExpose({
  formData,
  validateForm
})
</script>

<style lang="scss" scoped>
.el-select {
  width: 100% !important;
}
</style>

<style>
.avatar-uploader {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  height: 175px;
  width: 175px;
}

.avatar-uploader > .el-upload {
  height: 175px;
  width: 175px;
}

.avatar-uploader:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 175px;
  height: 175px;
  text-align: center;
}
</style>
